#ifndef __UTRASONIC_H__
#define __UTRASONIC_H__

#ifdef __cplusplus
extern "C" {
#endif

// Trigger Pin
#define GPIO_TRIGGER_PORT           GPIOC
#define GPIO_TRIGGER_PIN            GPIO_Pin_0
#define RCC_TRIGGER_PORT            RCC_AHB1Periph_GPIOC
#define TRIGGER_EXTI_SOURCE_PORT    EXTI_PortSourceGPIOC
#define TRIGGER_EXTI_SOURCE_PIN     EXTI_PinSource0
#define trigger_isr_handler         EXTI0_IRQHandler
#define TRIGGER_EXTI_LINE           EXTI_Line0
#define TRIGGER_EXTI_NVIC_CHANEL    EXTI0_IRQn

// Echo Pin
#define GPIO_ECHO_PORT              GPIOC
#define GPIO_ECHO_PIN               GPIO_Pin_1
#define RCC_ECHO_PORT               RCC_AHB1Periph_GPIOC
#define ECHO_EXTI_SOURCE_PORT       EXTI_PortSourceGPIOC
#define ECHO_EXTI_SOURCE_PIN        EXTI_PinSource1
#define echo_isr_handler            EXTI1_IRQHandler
#define ECHO_EXTI_LINE              EXTI_Line1
#define ECHO_EXTI_NVIC_CHANEL       EXTI1_IRQn

// Timer
#define UTRASOUND_TIMER             TIM1
#define utrasound_timer_isr_handler TIM1_CC_IRQHandler
#define UTRASOUND_TIMER_CLOCK       1000000 //1Mhz
#define UTRASOUND_TIMER_CLOCK_SRC    SystemCoreClock // APB2
#define UTRASOUND_TIMER_PRESCALE    ((UTRASOUND_TIMER_CLOCK_SRC / UTRASOUND_TIMER_CLOCK) - 1)

#define ECHO_TIMER                  TIM7
#define ECHO_TIMER_CLOCK            1000000 //1Mhz
#define ECHO_TIMER_CLOCK_SRC        (SystemCoreClock / 2) // APB1
#define ECHO_TIMER_PRESCALE         ((ECHO_TIMER_CLOCK_SRC / ECHO_TIMER_CLOCK) - 1)
#define echo_timer_isr_handler      TIM7_IRQHandler

struct x_gpio {
    GPIO_TypeDef *port;
    unsigned long pin;
    unsigned long rcc;
    unsigned long is_input;
    unsigned long is_exti;
    unsigned long exti_mode;
    unsigned long exti_src_port;
    unsigned long exti_src_pin;
    void (*exti_isr_handler)(void);
    unsigned long exti_line;
    unsigned long exti_nvic_channel;
};

enum x_utrasonic_mode {
    MODE1 = 1,
    MODE2 = 2
};

struct x_utrasonic {
    unsigned long is_object;
    unsigned long distance;
};

struct x_utrasonic_infos {
    struct x_gpio trigger_pin;
    struct x_gpio echo_pin;
    enum x_utrasonic_mode mode;
    // speed of sound and distance measurement
    //c = 331.3 + 0.606 × temperature (m/s)
    //distance = duration * c/2
    unsigned long temperature;
    struct x_utrasonic *data;
};

struct x_RTC {
    unsigned char sec;
    unsigned char min;
    unsigned char hour;
    unsigned char wday;
    unsigned char mday;
    unsigned char month;
    unsigned long year;
};

unsigned char  rtc_gettime(struct x_RTC *rtc);
unsigned char  rtc_settime  (struct x_RTC* rtc);

unsigned long open_utrasonic_module(struct x_utrasonic_infos *infos);
unsigned long start_utrasonic_measure(struct x_utrasonic_infos *infos, unsigned long (*utrasonic_callback)(struct x_utrasonic *data));
unsigned long is_object_detected(struct x_utrasonic_infos *infos);
unsigned long get_distance_to_object(struct x_utrasonic_infos *infos);
unsigned long close_utrasonic_module(struct x_utrasonic_infos *infos);

#ifdef __cplusplus
}
#endif
#endif // __UTRASONIC_H__